package com.heima.search.service.impl;

import com.heima.article.feign.ApArticleFeign;
import com.heima.common.dtos.ResponseResult;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ArticleDoc;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import com.heima.utils.common.ThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {

    private static final String ARTICLE_INDEX = "article";

    @Autowired
    private RestHighLevelClient highLevelClient;

    @Autowired
    private ApArticleFeign apArticleFeign;

    @Autowired
    private ApUserSearchService apUserSearchService;

    @Override
    public ResponseResult search(UserSearchDto dto) {

        try {

            ApUser apUser = (ApUser) ThreadLocalUtils.get();
            if (apUser != null) {
                apUserSearchService.save(apUser.getId(),dto.getSearchWords());
            }
            //参数处理
            if(dto.getPageSize()==0)dto.setPageSize(20);

            //创建搜索请求对象
            SearchRequest request = new SearchRequest(ARTICLE_INDEX);

            //设置各种条件
            //设置query
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",dto.getSearchWords()));
            boolQueryBuilder.must(QueryBuilders.rangeQuery("publishTime").lte(dto.getMinBehotTime().getTime()));
            request.source().query(boolQueryBuilder);

            //分页
            request.source().size(dto.getPageSize());

            //排序
            request.source().sort("publishTime", SortOrder.DESC);

            //高亮
            request.source().highlighter(
                        new HighlightBuilder().field("title")
                        .preTags("<font style='color: red; font-size: inherit;'>")
                        .postTags("</font>"));

            //执行查询
            SearchResponse response = highLevelClient.search(request, RequestOptions.DEFAULT);

            //处理结果
            SearchHits searchHits = response.getHits();

            List<ArticleDoc> articleDocs = new ArrayList<>();
            for(SearchHit searchHit:searchHits){
                String json = searchHit.getSourceAsString();
                ArticleDoc articleDoc = JsonUtils.toBean(json, ArticleDoc.class);

                //单独取出高亮内容
                HighlightField highlightField = searchHit.getHighlightFields().get("title");
                if(highlightField!=null){
                    String hTitle = highlightField.getFragments()[0].toString();
                    articleDoc.setH_title(hTitle);//存入高亮字段内容
                }

                articleDocs.add(articleDoc);
            }

            return ResponseResult.okResult(articleDocs);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Override
    public void saveToES(Long articleId) {
        ResponseResult<ApArticle> responseResult = apArticleFeign.findByArticleId(articleId);
        if (responseResult.getCode().equals(200)) {
            try {
                ApArticle apArticle = responseResult.getData();
                ArticleDoc articleDoc = BeanHelper.copyProperties(apArticle, ArticleDoc.class);

                IndexRequest request = new IndexRequest(ARTICLE_INDEX);
                request.id(articleId.toString()).source(JsonUtils.toString(articleDoc), XContentType.JSON);

                highLevelClient.index(request,RequestOptions.DEFAULT);

                log.info("写入ES成功，ID:{}",articleId);
            } catch (IOException e) {
                log.error("写入ES失败：{}"+e.getMessage());
            }
        }
    }

    @Override
    public void removeFromES(Long articleId) {
        try {
            DeleteRequest request = new DeleteRequest(ARTICLE_INDEX).id(articleId.toString());
            highLevelClient.delete(request,RequestOptions.DEFAULT);
            log.info("从ES删除成功，ID:{}",articleId);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("删除ES元素失败：{}"+e.getMessage());
        }
    }
}

